package com.me.myFramework.myAop.aop200.intercept.method;

import javax.annotation.Nonnull;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Method;
import java.util.List;

/**
 * 自己实现 AOP-200：  <p></p>
 *
 * AOP联盟：该接口是执行方法增强的切面执行器，封装了如下公共逻辑：
 * 切面还没有执行完的话，就继续执行下一个切面，否则调用目标方法
 *
 * @author ME
 * @date 2021/9/26
 */
public class ReflectiveMethodInvocation implements MethodInvocation {

    private Object target;
    private Method method;
    private Object[] arguments;
    /** 执行切面逻辑的拦截器 */
    private List<MethodInterceptor> interceptors;

    /** 标记是否调用目标方法 */
    private int currentInterceptorIndex = -1;

    public ReflectiveMethodInvocation(Object target, Method method, Object[] args, @Nonnull List<MethodInterceptor> interceptors) {
        this.target = target;
        this.method = method;
        this.arguments = args;
        this.interceptors = interceptors;
    }

    /**
     * 执行此拦截点，并进入到下一个连接点
     *
     * @return 返回值
     * @throws Throwable Throwable
     */
    @Override
    public Object proceed() throws Throwable {
        // TODO 增强逻辑都执行过之后，需要执行原始方法，先简单使用标记实现
        //  后续此处需要改成责任链模式模式
        if (currentInterceptorIndex == interceptors.size() -1) {
            return method.invoke(target, arguments);
        }
        else {
            return this.interceptors.get(++currentInterceptorIndex).invoke111(method, arguments, target, interceptors, currentInterceptorIndex);
        }
    }

    @Override
    public Object getThis() {
        return target;
    }

    @Override
    public Method getMethod() {
        return method;
    }

    @Override
    public Object[] getArguments() {
        return arguments;
    }

}
